package uniandes.dermatologia.models;

import java.util.Date;

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

import uniandes.dermatologia.resources.Constants;

@JsonIgnoreProperties({ "affectedAreas" })
public class PhysicalExamination {

	private Shape shape;

	private LesionNumber number;

	private Distribution distribution;

	private LesionType lesionType;

	private Border border;

	private String bodyParts;

	private String symptoms;

	private String past;
	
	private Date startDate;

	private boolean[] affectedAreas;

	public PhysicalExamination() {
		symptoms = "";
		past = "";
		bodyParts = "";
	}

	public enum Shape {
		annular, circinate, dome_shaped, ragged, oval, pedunculated, round, umbilicated, other
	}

	public enum LesionNumber {
		disseminated, multiple, recurrent, solitary, other
	}

	public enum Distribution {
		asymmetrical, confluent, scattered, symmetrical, other
	}

	public enum LesionType {
		atrofica, cyst, macule, nodule, patch, plaque, pustule, ulcer, vesicle, other
	}

	public enum Border {
		poorly_demarcated, well_demarcated
	}

	public enum Symptom {
		alopecia, blanching, desquamation, pain, edema, eruption, excoriation, exfoliation, hemorrhage, pigmentation, pruritus, fever, facial_paralysis, weight_loss, systemic_symptoms, other
	}

	public enum Past {
		anemia, arthritis, malnutrition, diabetes, epileptic, hypertension, hypotension, myocarditis, neuropathy, vih, other
	}

	public LesionNumber getNumber() {
		return number;
	}

	public void setNumber(LesionNumber number) {
		this.number = number;
	}

	public Shape getShape() {
		return shape;
	}

	public void setShape(Shape shape) {
		this.shape = shape;
	}

	public Distribution getDistribution() {
		return distribution;
	}

	public void setDistribution(Distribution distribution) {
		this.distribution = distribution;
	}

	public LesionType getLesionType() {
		return lesionType;
	}

	public void setLesionType(LesionType lesionType) {
		this.lesionType = lesionType;
	}

	public Border getBorder() {
		return border;
	}

	public void setBorder(Border border) {
		this.border = border;
	}

	public String getBodyParts() {
		return bodyParts;
	}

	public void setBodyParts(String bodyParts) {
		this.bodyParts = bodyParts;
		String[] parts = bodyParts.split(" , ");
		boolean[] areas = new boolean[Constants.AFFECTED_AREAS.length]; 
		
		int i = 0;
		for(String s : Constants.AFFECTED_AREAS)
		{
			if(contains(parts, s))
			{
				areas[i] = true;
			}
			i++;
		}
	}

	public boolean[] getAffectedAreas() {
		return affectedAreas;
	}

	public void setAffectedAreas(boolean[] affectedAreas) {
		this.affectedAreas = affectedAreas;
	}

	public String affectedAreasString() {
		String result = Constants.AFFECTED_AREAS[0];

		for (int i = 1; i < affectedAreas.length; i++) {
			if (affectedAreas[i]) {
				result = result + " , " + Constants.AFFECTED_AREAS[i];

			}
		}
		bodyParts = result;
		return result;

	}

	public String getSymptoms() {
		return symptoms;
	}

	public void setSymptoms(String symptoms) {
		this.symptoms += symptoms + " ";
	}
	
	public void trimSymptoms()
	{
		this.symptoms.trim();
	}
	
	public void cleanSymptoms() {
		this.symptoms = "";
	}

	public String getPast() {
		return past;
	}

	public void setPast(String past) {
		this.past += past + " ";
	}
	
	public void cleanPast() {
		this.past = "";
	}
	
	public void trimPast()
	{
		this.past.trim();
	}

	/**
	 * @return the startDate
	 */
	public Date getStartDate() {
		return startDate;
	}

	/**
	 * @param startDate the startDate to set
	 */
	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}
	
	public String getBorderString()
	{
		String borderString = "";
		
		if(border == Border.poorly_demarcated)
		{
			borderString = "poorly_demarcated";
		}
		else if(border == Border.well_demarcated)
		{
			borderString = "well_demarcated";
		}
		return borderString;
	}
	
	public void setBorderFromString(String borderString)
	{
		if(borderString.equals("poorly_demarcated"))
		{
			border = Border.poorly_demarcated;
		}
		else
		{
			border = Border.well_demarcated;
		}
	}

	public String getDistributionString() {
		String distributionString = "";
		
		switch(distribution)
		{
			case asymmetrical:
				distributionString = "asymmetrical";
				break;
			case confluent:
				distributionString = "confluent";
				break;
			case scattered:
				distributionString = "scattered";
				break;
			case symmetrical:
				distributionString = "symmetrical";
				break;
			case other:
				distributionString = "other";
				break;
		}
		
		return distributionString;
	}
	
	public void setDistributionFromString(String distributionString)
	{
		if(distributionString.equals("asymmetrical"))
		{
			distribution = Distribution.asymmetrical;
		}
		else if(distributionString.equals("confluent"))
		{
			distribution = Distribution.confluent;
		}
		else if(distributionString.equals("scattered"))
		{
			distribution = Distribution.scattered;
		}
		else if(distributionString.equals("symmetrical"))
		{
			distribution = Distribution.symmetrical;
		}
		else if(distributionString.equals("other"))
		{
			distribution = Distribution.other;
		}
	}

	public String getLesionTypeString() {
		String lesionTypeString = "";
		switch(lesionType)
		{
			case atrofica:
			lesionTypeString = "atrofica";
			break;
			case cyst:
				lesionTypeString = "cyst";
				break;
			case macule:
				lesionTypeString = "macule";
				break;
			case nodule:
				lesionTypeString = "nodule";
				break;
			case other:
				lesionTypeString = "other";
				break;
			case patch:
				lesionTypeString = "patch";
				break;
			case plaque:
				lesionTypeString = "plaque";
				break;
			case pustule:
				lesionTypeString = "pustule";
				break;
			case ulcer:
				lesionTypeString = "ulcer";
				break;
			case vesicle:
				lesionTypeString = "vesicle";
				break;
		}
		return lesionTypeString;
	}
	
	public void setLesionTypeFromString(String lesionTypeString)
	{
		if(lesionTypeString.equals("atrofica"))
		{
			lesionType = LesionType.atrofica;
		}
		else if(lesionTypeString.equals("cyst"))
		{
			lesionType = LesionType.cyst;
		}
		else if(lesionTypeString.equals("macule"))
		{
			lesionType = LesionType.macule;
		}
		else if(lesionTypeString.equals("nodule"))
		{
			lesionType = LesionType.nodule;
		}
		else if(lesionTypeString.equals("other"))
		{
			lesionType = LesionType.other;
		}
		else if(lesionTypeString.equals("patch"))
		{
			lesionType = LesionType.patch;
		}
		else if(lesionTypeString.equals("plaque"))
		{
			lesionType = LesionType.plaque;
		}
		else if(lesionTypeString.equals("pustule"))
		{
			lesionType = LesionType.pustule;
		}
		else if(lesionTypeString.equals("ulcer"))
		{
			lesionType = LesionType.ulcer;
		}
		else if(lesionTypeString.equals("vesicle"))
		{
			lesionType = LesionType.vesicle;
		}
		else if(lesionTypeString.equals("atrofica"))
		{
			lesionType = LesionType.atrofica;
		}
	}

	public String getNumberString() {
		String numberString = "";
		switch(number)
		{
			case disseminated:
				numberString = "disseminated";
				break;
			case multiple:
				numberString = "multiple";
				break;
			case other:
				numberString = "other";
				break;
			case recurrent:
				numberString = "recurrent";
				break;
			case solitary:
				numberString = "solitary";
				break;
		}
		return numberString;
	}
	
	public void setNumberFromString(String numberString)
	{
		if(numberString.equals("disseminated"))
		{
			number = LesionNumber.disseminated;
		}
		else if(numberString.equals("multiple"))
		{
			number = LesionNumber.multiple;
		}
		else if(numberString.equals("other"))
		{
			number = LesionNumber.other;
		}
		else if(numberString.equals("recurrent"))
		{
			number = LesionNumber.recurrent;
		}
		else if(numberString.equals("solitary"))
		{
			number = LesionNumber.solitary;
		}
	}

	public String getShapeString() {
		String shapeString = "";
		switch (shape) {
		case annular:
			shapeString = "annular";
			break;
		case circinate:
			shapeString = "circinate";
			break;
		case dome_shaped:
			shapeString = "dome_shaped";
			break;
		case other:
			shapeString = "other";
			break;
		case oval:
			shapeString = "oval";
			break;
		case pedunculated:
			shapeString = "pedunculated";
			break;
		case ragged:
			shapeString = "ragged";
			break;
		case round:
			shapeString = "round";
			break;
		case umbilicated:
			shapeString = "umbilicated";
			break;
		}
		return shapeString;
	}
	
	public void setShapeFromString(String shapeString)
	{
		if(shapeString.equals("annular"))
		{
			shape = Shape.annular;
		}
		else if(shapeString.equals("circinate"))
		{
			shape = Shape.circinate;
		}
		else if(shapeString.equals("dome_shaped"))
		{
			shape = Shape.dome_shaped;
		}
		else if(shapeString.equals("other"))
		{
			shape = Shape.other;
		}
		else if(shapeString.equals("oval"))
		{
			shape = Shape.oval;
		}
		else if(shapeString.equals("pedunculated"))
		{
			shape = Shape.pedunculated;
		}
		else if(shapeString.equals("ragged"))
		{
			shape = Shape.ragged;
		}
		else if(shapeString.equals("round"))
		{
			shape = Shape.round;
		}
		else if(shapeString.equals("umbilicated"))
		{
			shape = Shape.umbilicated;
		}
	}
	
	/**
	 * Checks wether the haystack contains the needle.
	 * @param haystack The array where the instance is searched.
	 * @param needle The instance to look for.
	 * @return <b><i>True</i></b> if the needle is within the haystack.
	 */
	public boolean contains(Object[] haystack, Object needle)
	{
		boolean contains = false;
		Object compare;
		for(int i = 0; i < haystack.length && !contains; i ++)
		{
			compare = haystack[i];
			if(needle.equals(compare))
			{
				contains = true;
			}
		}
		return contains;
	}
	
	
}
